#include <conio.h>
#include "../../HeadFiles/StandardHeads.h"

#include "../../HeadFiles/GetTime.h"
#include "../../HeadFiles/InputCheck.h"

void displayAllClients(struct ClientNode * head)
{
    int idx = 0;
    while(head != NULL) {
        puts(SPLIT_STR);

        // 以下代码用来展示每个记录的细节信息， 做成代码块方便折叠
        {
            printf("Client #%d:\n", ++idx);
            printf("ClientName = %s\n", head->clientName);
        }
        head = head->nextClient;
    }
    puts(SPLIT_STR);
    puts("Clients Display Finished");
}

void displayThisClient(struct ClientNode * clientDisplayPtr)
{
    // recordDisplayPtr是为了在主函数中区分不同的链表当前展示指针
    // 在函数里写成this方便阅读
    struct ClientNode * this = clientDisplayPtr;
    puts(SPLIT_STR);
    printf("Participation Date(dd-mm-yyyy): %d-%d-%d\n", this->day, this->month, this->year);

    puts(SPLIT_STR);

    printf("ClientName: %s\n", this->clientName);
    printf("Client Lv: %d\n", this->lv);
    printf("Balance: %.2f\n", this->balance);
    puts(SPLIT_STR);
}

void buildClientChain(struct ClientNode ** head, struct ClientNode ** tail)
{
    FILE * clientFILE = fopen("../Data/ClientChainData/ClientData.txt", "r");

    * head = * tail = NULL; // 先初始化防止不操作返回野值
    int opt;
    fscanf(clientFILE, "%d", &opt); // opt==-1为停止添加节点，==1为添加新节点
    struct ClientNode * pre = NULL, * now = NULL;
    while(opt == 1)
    {
        now = (struct ClientNode *)malloc(sizeof(struct ClientNode));
        now->nextClient = now->preClient = NULL; // 申请完空间直接把指针初始化

        // 以下代码用来录入每个记录的细节信息， 做成代码块方便折叠
        {
            fscanf(clientFILE, "%s", &now->clientName);
            fscanf(clientFILE, "%d", &now->lv);
            fscanf(clientFILE, "%lf", &now->balance);
            fscanf(clientFILE, "%d %d %d", &now->day, &now->month, &now->year);
            // fscanf("")
        }

        if(* head == NULL)
        {
            * head = now;
        }else{
            pre->nextClient = now;
            now->preClient = pre;
        }
        pre = now;
        fscanf(clientFILE,"%d", &opt);
    }
    * tail = now;

    fclose(clientFILE);
    clientFILE = NULL;
}

void  delClient(struct ClientNode ** head, struct ClientNode ** tail, struct ClientNode * p)
{
    // ** head, ** tail是头尾指针的地址，直接对其解引用，然后加以修改
    // 注意，p是指向节点的指针，和head，tail不一样
    if(* head == p || * tail == p)
    {
        // 如果要删除的节点比较特殊，是头或尾节点
        if(* head == p && * tail == p)
        {
            // 要删除的节点既是头又是尾， 此时链表只有这一个元素
            free(* head);
            * head = * tail = NULL; // free后内存被清理，但是指针仍指向该地址，必须置空防bug
            return ;
        }
        if(* head == p && * tail != p)
        {
            // 要删除的节点是头，但不是尾
            struct ClientNode * temp = * head;
            * head = (* head)->nextClient;
            (* head)->preClient = NULL;
            free(temp);
            return ;
        }
        if(* head != p && * tail == p)
        {
            // 要删除的节点是尾，但不是头
            struct ClientNode * temp = * tail;
            * tail = (* tail)->preClient;
            (* tail)->nextClient = NULL;
            free(temp);
            return ;
        }
    }
    // 如果删除的节点不是头或者尾的特殊情况
    // 注意，p是指向节点的指针，和head，tail不一样
    p->nextClient->preClient = p->preClient;
    p->preClient->nextClient = p->nextClient;
    free(p);
}

void addClient(struct ClientNode ** head, struct ClientNode ** tail)
{
    struct ClientNode * now = (struct ClientNode *) malloc(sizeof(struct ClientNode));
    now->preClient = now->nextClient = NULL;    // 申请新节点第一件事就是指针初始化！非常重要！
    now->balance = 0.00;    //新创建的用户余额为0
    if(* head == NULL && * tail == NULL)
    {
        // 增加链表第一个节点,该节点即是头又是尾
        puts("You are now creating the 1st client");
        * head = * tail = now;

        // 输入具体信息的代码块
        {
            puts("Input client name:");
            scanf("%s", now->clientName);
            puts("Input client Lv:");
            char tempLv[STR_MAX_LEN];
            scanf("%s", tempLv);
            while(!(isFullDigit(tempLv) && strlen(tempLv) <= 2))
            {
                puts("Illegal input Detected!Try again:");
                scanf("%s", tempLv);
            }
            now->lv = strToInt(tempLv);
            getCurrentTime(&now->year, &now->month, &now->day);
        }
        return ;
    }else{
        // 不是第一个节点，则只需接在最后节点(tail)的后面
        (* tail)->nextClient = now;
        now->preClient = * tail;
        * tail = now;

        // 输入具体信息
        {
            puts("Input client name:");
            scanf("%s", now->clientName);
            puts("Input client Lv:");
            char tempLv[STR_MAX_LEN];
            scanf("%s", tempLv);
            while(!(isFullDigit(tempLv) && strlen(tempLv) <= 2))
            {
                puts("Illegal input Detected!Try again:");
                scanf("%s", tempLv);
            }
            now->lv = strToInt(tempLv);
            getCurrentTime(&now->year, &now->month, &now->day);
        }
        return ;
    }
}

void rebuildClientFile(struct ClientNode * head)
{
    FILE * clientFile = fopen("../Data/ClientChainData/ClientData.txt", "w");

    while(head != NULL)
    {
        // 输出节点所有信息的代码块，在测试时，暂时只输出unit count
        {
            fprintf(clientFile, "1\n");
            fprintf(clientFile, "%s\n", head->clientName);
            fprintf(clientFile, "%d\n", head->lv);
            fprintf(clientFile, "%.2f\n", head->balance);
            fprintf(clientFile, "%d %d %d\n", head->day, head->month, head->year);
            fprintf(clientFile, "\n");
            head = head->nextClient;
        }
    }
    fputs("-1", clientFile);

    fclose(clientFile);
    clientFile = NULL;
}
void changeLv(struct ClientNode * p)
{
    printf("Input new lv\n");
    char newLv = getche();
    while(!(newLv == '1' || newLv == '2' || newLv == '3' || newLv == '4' || newLv == '5' || newLv == '0'))
    {
        puts("Illegal input detected! Try again:");
        newLv = getche();
    }
    p->lv = newLv - '0';
}

